/*************
author:: libo
license:: MIT
*****************/

#ifndef LIBCELL_ITERATOR_H
#define LIBCELL_ITERATOR_H

#include "Mesh_Frame.h"
#include "libcell_iteratorc.h"
#include<iterator/cstruct_iterator.h>

#include<tools/intrbtree.h>
#include<tools/intrbtree_iterator.h>
#define iterator_v lib_cell_iterator_vertices
#define iterator_f lib_cell_iterator_faces
#define iterator_c lib_cell_iterator_cells
#define iterator_edge lib_cell_iterator_edge

#define quote lib_cell_quote

static inline iterator_v operator++(iterator_v& vv_)
{
    if(vv_.value==NULL)
    {
        vv_.it++;
    }
    else
    {
        (vv_.i)++;
    }
    return vv_;
}
static inline iterator_v operator++(iterator_v&vv_,int)
{
    iterator_v vv=vv_;
    if(vv_.value==NULL)
    {
        vv_.it++;
    }
    else
    {
        (vv_.i)++;
    } 
    return vv;
}
static inline template_v* quote( iterator_v vv_)
{
    return vv_.value==NULL?((template_v*)(*(vv_.it))):vv_.value[vv_.i];
}


static inline template_v operator*(iterator_v &vv_)
{
    return *quote(vv_);
}

static inline bool operator!=(const iterator_v&v_1,const iterator_v& v_2)
{
    return !(v_1.value==v_2.value&&v_1.i==v_2.i&&v_1.it==v_2.it); 
}
static inline bool operator == (const iterator_v&v_1,const iterator_v&v_2)
{
    return (v_1.value==v_2.value&&v_1.i==v_2.i&&v_1.it==v_2.it);
}

static inline iterator_f operator++(iterator_f& f_)
{
    if(f_.node.value==NULL)
    {
        f_.it++;
    }
    else
    {
        f_.node--;
    }
    
    return f_;
}
static inline iterator_f operator++(iterator_f&f_,int)
{
    iterator_f f1=f_;
    if(f_.node.value==NULL)
    {
        f_.it++;
    }
    else
    {

        (f_.node)--;
    }
    return f1;
}
static inline template_f* quote(iterator_f f_)
{

    return  f_.node.value==NULL?((template_f*)(*(f_.it))):((template_f*)(*(f_.node)));
}

static inline template_f operator*(iterator_f&f_)
{
    return *quote(f_);
}

static inline bool operator!=(const iterator_f& f_1,const iterator_f& f_2)
{
    return !(f_1.node.value==f_2.node.value&&f_1.it==f_2.it);
  
}
static inline bool operator==(const iterator_f& f_1,const iterator_f&f_2)
{
    return (f_1.node.value==f_2.node.value&&f_1.it==f_2.it);
}

// void iterator_c_init(iterator_c*);
static inline iterator_c operator++(iterator_c& c_)
{
    if(c_.node.value==NULL)
    {
        c_.it++;
    }
    else
    {
        c_.node++;
    }
    return c_;
}
static inline iterator_c operator++(iterator_c &c_,int)
{
    iterator_c c_1=c_;
    if(c_.node.value==NULL)
    {
        c_.it++;
    }
    else
    {
        (c_.node)++;
    }
    return c_1;

}


static inline template_c* quote(iterator_c c_)
{
    return c_.node.value==NULL?((template_c*)(*(c_.it))):((template_c*)(*(c_.node)));

}
static inline template_c operator*(iterator_c&c_)
{
    return *quote(c_);
}

static inline bool operator!=(const iterator_c& c_1,const iterator_c& c_2)
{
    return !(c_1.node.value==c_2.node.value&&c_1.it==c_2.it);
   
}
static inline bool operator== (const iterator_c&c_1,const iterator_c&c_2)
{
    return (c_1.node.value==c_2.node.value&&c_1.it==c_2.it);
}
static inline iterator_hf operator++(iterator_hf& it)
{
    if(it.node.value==NULL)
    {
        it.it++;
    } 
    else
    {
        it.node--;
    }
    return it;
}
static inline iterator_hf operator++(iterator_hf& it,int)
{
    iterator_hf hf_=it;
    if(it.node.value==NULL)
    {
        it.it++;
    }
    else
    {
        it.node--;
    }
    return hf_;
}
static inline template_hf* quote(iterator_hf it)
{
    return it.node.value==NULL?((template_hf*)(*(it.it))):((template_hf*)(*(it.node)));
}

static inline template_hf operator*(iterator_hf& it)
{
    return *quote(it);

}
static inline bool operator!=(const iterator_hf& it1,const iterator_hf&it2)
{
    return !(it1.node.value==it2.node.value&&it1.it==it2.it);
}
static inline bool operator== (const iterator_hf&it1,const iterator_hf&it2)
{
    return (it1.node.value==it2.node.value&&it1.it==it2.it);
}

iterator_edge operator++(iterator_edge&);
iterator_edge operator++(iterator_edge&,int);
static inline bool operator!=(const iterator_edge&ie1,const iterator_edge &ie2)
{
    return !(ie1.v==ie2.v&&ie1.f==ie2.f);
}
//auto Mesh_vertices_begin(struct Mesh*);
//auto Mesh_veritces_end(struct Mesh*);
#undef iterator_v 
#undef iterator_f 
#undef iterator_c 
#undef iterator_edge 

#undef quote
#endif
